#include "movebutton.h"
#include <QPainter>
#include <QEvent>
#include <QSizePolicy>

MoveButton::MoveButton(QWidget *parent)
    : QPushButton(parent)
{
    connect(this, SIGNAL(clicked()), this, SLOT(clicked()));
    setSize(m_size);
    m_animation.setTargetObject(this);
    m_animation.setDuration(300);
    m_animation.setPropertyName("value");
    connect(&m_animation, SIGNAL(finished()), this, SLOT(animationFinished()));
}

void MoveButton::setSize(QSize size)
{
    m_size = size;
    updateFrame();
}

void MoveButton::setBuddy(QWidget *buddy)
{
    if (m_buddy) {
        m_buddy->removeEventFilter(this);
    }
    m_buddy = buddy;
    m_minSize = m_buddy->minimumSize();
    m_maxSize = m_buddy->maximumSize();
    m_buddy->installEventFilter(this);
}


void MoveButton::setExtended(bool value)
{
    if (!m_buddy) {
        return;
    }
    m_extended = value;

    if (!m_extended) {
        m_buddyWidth = m_buddy->width();
    }
    m_buddy->setVisible(true);
    m_animation.setStartValue(m_extended ? 0 : m_buddyWidth);
    m_animation.setEndValue(m_extended ?  m_buddy->width() : 0);
    m_animation.start();
}

void MoveButton::clicked()
{
    if (!m_buddy) {
        return;
    }

    m_extended = !m_extended;
    setExtended(m_extended);
    if (m_extended) {
        emit extend();
    } else {
        emit retract();
    }
    emit extended(m_extended);
}

void MoveButton::enterEvent(QEnterEvent *event)
{
    m_hovered = true;
    updateFrame();
}

void MoveButton::leaveEvent(QEvent *event)
{
    m_hovered = false;
    updateFrame();
}

bool MoveButton::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == m_buddy) {
        if (event->type() == QEvent::Paint) {
            moveButton();
        }
    }
    return false;
}

void MoveButton::setValue(int value)
{
    if (m_buddy) {
        m_buddy->setFixedWidth(value);
        this->moveButton();
    }
}

void MoveButton::updateFrame()
{
    qreal var  = qMax(m_size.width(), m_size.height());
    this->resize(var, var);

    // 外部轮廓区域
    qreal extralSize = m_hovered ? 8 : 10;
    qreal width = m_size.width() - extralSize;
    qreal height = m_size.height() - extralSize;
    m_border = {{0,     extralSize / 2},
                {width, height / 6 + extralSize / 2},
                {width, height / 6 * 5 + extralSize / 2},
                {0,     m_size.height() - extralSize / 2}};


    // 中间等边三角形，计算高和边长一半
    qreal h = width - 2;
    qreal halfSide = h / sqrt(3);


    // 展开和缩回下不同箭头方向
    m_extendDirect = {{2.0, m_size.height() / 2.0 - halfSide},
                      {h + 2, m_size.height() / 2.0},
                      {2, m_size.height() / 2.0 + halfSide}};

    m_retractDirect = {{h + 2, m_size.height() / 2.0 - halfSide},
                       {2, m_size.height() / 2.0},
                       {h + 2, m_size.height() / 2.0 + halfSide}};

    moveButton();
}

void MoveButton::moveButton()
{
    if (!m_buddy) {
        return;
    }
    update();
    auto rect = m_buddy->rect();
    if (m_buddy->isVisible() == false) {
        rect.setWidth(0);
    }

    QPoint p = {m_buddy->pos().x() + rect.width(), rect.height()/2 - this->height() / 2};
    this->move(p);
}

void MoveButton::animationFinished()
{
    if (m_buddy) {
        m_buddy->setMinimumSize(m_minSize);
        m_buddy->setMaximumSize(m_maxSize);
        m_buddy->setVisible(m_extended);
    }
}

void MoveButton::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    QPen pen;
    pen.setWidth(4);
    pen.setColor(Qt::white);
    pen.setCapStyle(Qt::RoundCap);
    QBrush brush(Qt::white);
    painter.setPen(pen);
    painter.setBrush(brush);
    painter.drawPolygon(m_border);

    pen.setWidth(1);
    pen.setCapStyle(Qt::SquareCap);
    pen.setColor(Qt::darkGray);

    painter.setPen(pen);
    brush.setColor(m_hovered ? Qt::green : Qt::darkGray);
    painter.setBrush(brush);
    painter.drawPolygon(m_extended ? m_retractDirect : m_extendDirect);
}
